package com.heima.search.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.search.service.SearchService;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.jsoup.helper.StringUtil;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;


@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 基本搜索业务
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {
       //TODO
        //创建搜索请求
        SearchRequest request = new SearchRequest("app_info_article");

        //设置请求参数
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //根据关键字查询
        if (!StringUtil.isBlank(dto.getSearchWords())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",dto.getSearchWords()));
        }

        request.source().query(boolQueryBuilder);

        //根据发布时间进行排序
        request.source().sort("publishTime", SortOrder.DESC);

        //进行排序
        request.source().from(dto.getFromIndex()).size(dto.getPageSize());

        //进行高亮处理
        request.source()
                .highlighter(new HighlightBuilder()
                        .field("title")
                        .preTags("<em style = 'color :blue; font-size:18px'>")
                        .postTags("</em>")
                        .requireFieldMatch(false)
                );

        //发起请求
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);

            //获取相应结果
            SearchHits hits = response.getHits(); //命中的一级请求
            SearchHit[] hitsHits = hits.getHits(); //命中的二级请求

            ArrayList<ApArticle> apArticleList = new ArrayList<>();

            //遍历数组获取每一个元素
            for (SearchHit hit : hitsHits) {
                //获取JSON对象
                String hitJson = hit.getSourceAsString();

                //反序列化
                ApArticle apArticle = JSON.parseObject(hitJson, ApArticle.class);
//                apArticle.setTitle(apArticle.getTitle());
//                apArticleList.add(apArticle);

                //处理高亮字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (ObjectUtil.isNotEmpty(highlightFields) && highlightFields.size() >0){
                    HighlightField highlightField = highlightFields.get("title");
                    if (highlightField != null ){
                        String title = highlightField.getFragments()[0].toString();
                        apArticle.setH_title(title);
                    }
                }
                apArticleList.add(apArticle);
            }
            return ResponseResult.okResult(apArticleList);

        } catch (IOException e) {
            e.getStackTrace();
        }

        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }


    /**
     * 文章审核通过后新增数据到索引库
     *
     * @param apArticle
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("insert.queue"),
            exchange = @Exchange("insert.exchange"),
            key = {"insert.exchange"}
    ))
    public void insertSearch(ApArticle apArticle) {

        //创建请求对象
        IndexRequest request = new IndexRequest("insert.exchange").id(apArticle.getId().toString());

        //添加请求参数
        String jsonString = JSON.toJSONString(apArticle);
        request.source(jsonString, XContentType.JSON);

        try {
            //发送请求
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);

        } catch (IOException e) {
            e.getStackTrace();
        }
    }


    /**
     * 自动补全功能
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(UserSearchDto dto) {
       //TODO
        return null;
    }
}
